<template>
  <div class="input-wrap gap-col-5">
    <div class="gap-row-4" :class="{ 'd-flex justify-space-between': tailText }">
      <label v-if="label" class="font-size-12 font-weight-400 line-height-120">{{ label }}</label>
      <span
        v-if="subLabel"
        class="font-size-12 font-weight-500 line-height-120"
        :class="subLabelStatus ? 'text-primary-green' : 'text-primary'"
        >{{ subLabel }}</span
      >
      <span v-if="subtitle" class="font-size-10 font-weight-400 line-height-120 pointer">{{ subtitle }}</span>
      <span
        v-if="tailText"
        class="font-size-10 font-weight-400 line-height-120"
        :class="[tailTextColor]"
        @click="() => emits('click:tail-text')"
      >
        {{ tailText }}
      </span>
    </div>
    <div class="input">
      <input
        v-model="value"
        :type="type"
        class="font-size-14 font-weight-500 line-height-140"
        :class="{
          error: !!errMsg,
          'bg-surface': !bgDark,
          'bg-background': bgDark,
          'append-icon': !!appendIcon,
        }"
        :style="{
          ...inputPaddingLeft,
        }"
        :placeholder="placeholder || $t('placeholder.message')"
        :disabled="disabled"
        :value="value"
        :inputmode="inputMode"
        @blur="emits('blur')"
        @focus="emits('focus')"
      />
      <div class="px-5"></div>
      <Icon
        v-if="password"
        class="password-switch"
        size="17"
        :name="pwdHide ? 'hide' : 'show'"
        @click="pwdHide = !pwdHide"
      ></Icon>
      <Icon
        v-if="!!appendIcon && showAppendIconOnType"
        class="password-switch"
        size="17"
        :name="appendIcon"
        @click="emits('click:append-icon')"
      ></Icon>
      <Icon
        v-if="!!prependIcon"
        class="prepend-icon"
        size="17"
        :name="prependIcon"
        @click="emits('click:prepend-icon')"
      ></Icon>
      <div v-if="!!prependText" class="prepend-text text-subtitle-x" ref="prependTextRef">
        {{ prependText }}
      </div>
    </div>
    <div v-if="errMsg" class="err-msg font-size-12 font-weight-400 line-height-120 text-primary-x">
      {{ errMsg }}
    </div>
  </div>
</template>

<script setup>
import { computed, ref } from 'vue'
import { $t } from '@/i18n'

const props = defineProps({
  label: { type: String },
  subLabel: { type: String },
  subLabelStatus: { type: Boolean, default: false },
  subtitle: { type: String },
  tailText: { type: String },
  tailTextColor: { type: String, default: 'text-primary' },
  modelValue: { type: [String, Number], required: true },
  errMsg: { type: String, default: '' },
  placeholder: { type: String },
  password: { type: Boolean, default: false },
  number: { type: Boolean, default: false },
  search: { type: Boolean, default: false },
  disabled: { type: Boolean, default: false },
  bgDark: { type: Boolean, default: false },
  appendIcon: { type: String, default: '' },
  prependIcon: { type: String, default: '' },
  prependText: { type: String, default: '' },
  value: { type: String },
  inputMode: { type: String, default: 'text' },
  typingAppend: { type: Boolean, default: false },
  trim: { type: Boolean, default: false },
})

const emits = defineEmits([
  'update:modelValue',
  'click:append-icon',
  'click:prepend-icon',
  'blur',
  'focus',
  'click:tail-text',
])

const value = computed({
  get() {
    return props.modelValue
  },
  set(newValue) {
    const _value = props.trim ? newValue.trim() : newValue
    emits('update:modelValue', _value)
  },
})

const pwdHide = ref(true)
const type = computed(() =>
  props.password && pwdHide.value ? 'password' : props.number ? 'number' : props.search ? 'search' : 'text',
)
const showAppendIconOnType = computed(() => (props.typingAppend ? !!value.value : true))

const prependTextRef = ref(null)
const REM = 16
const inputPaddingLeft = computed(() => {
  const paddingLeft = prependTextRef.value
    ? Math.round(prependTextRef.value?.offsetWidth || 0) + 4
    : props.prependIcon
    ? 1.25 * REM + 20
    : REM
  return { paddingLeft: `${paddingLeft / REM + 1}rem` }
})
</script>

<style lang="scss" scoped>
.input-wrap {
  display: flex;
  flex-direction: column;

  .input {
    position: relative;
    .password-switch {
      position: absolute;
      top: 0.71875rem;
      right: 1rem;
    }

    .prepend-icon {
      position: absolute;
      top: 0.71875rem;
      left: 1.25rem;
    }

    .prepend-icon__input {
      padding-left: calc(1.25rem + 0.75rem + 1rem);
    }

    .prepend-text {
      position: absolute;
      top: 0.61875rem;
      left: 1rem;

      font-size: 0.875rem;
      font-style: normal;
      font-weight: 500;
      line-height: 140%;
    }

    .prepend-text__input {
      padding-left: calc(1rem + 0.875rem + 0.5rem);
    }

    .append-icon {
      padding-right: calc(1rem + 1.06rem + 0.5rem);
    }

    input {
      width: 100%;
      height: 2.5rem;
      padding: 0 1rem;
      border-radius: 0.625rem;
      outline: none;
      letter-spacing: 0.2px;

      &.error {
        border: 0.0625rem solid rgb(var(--v-theme-primary-x));
        background: linear-gradient(0deg, rgba(235, 0, 27, 0.1) 0%, rgba(235, 0, 27, 0.1) 100%),
          rgb(var(--v-theme-background));
      }

      &::placeholder {
        font-weight: 400;
        color: rgb(var(--v-theme-input));
      }

      &:disabled {
        opacity: 0.5;
      }
    }
  }

  .err-msg {
    text-align: right;
  }
}
</style>
